<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>



    console.log(Function.prototype.__proto__ === Object.prototype) // true


    /* 
    function Function (){}
    Function.prototype.call/apply/bind = function (){}
    function Object(){}
    */


    // JS内置了一些构造函数或对象: Function / Object / Array / String / Reg / Date / Math
    // js引擎在执行我们的代码前, 会会执行内置的代码, 定义一些内置的类型和对象
    // js引擎: 一套浏览器内置的程序代码, 作用: 解析执行js代码

    /* 
      function Function () {}
      function Object () {}
      Function.prototype.call = function () {}
      Object.prototype.toString = function () {}
      JS引擎在执行我们的代码前， 先执行它内部的代码： 定义了一些构造函数
    */
    // 我们定义的函数的原型对象是Object的实例
    function Fn() {
      
    }
    // console.log(Fn.prototype)
    // console.log(Fn.prototype.__proto__===Object.prototype)

    // const fn = new Fn()
    // console.log(fn.__proto__.__proto__.__proto__) 
   

    console.log(Function.prototype.__proto__ === Object.prototype) // true
    console.log(Function.prototype)  // 它是一个函数, 不可能是Object的实例
    /* 内部加上的:  Function.prototype.__proto__ = Object.prototype */
    /* 为什么要加? */

    /* 
    1. 实例对象隐式原型(__proto__)等于对应的构造函数的显式原型(prototype)
    2. 我们定义的函数的原型对象是Object的实例对象 ==> 我们的函数.prototype.__proto__ === Object.prototype
    3. Object的原型对象的隐式原型属性为null
    4. 所有函数都是Function的实例, 包括它自己 ==> 任意函数.__proto__ = Function.prototype
    */

    /* 
    JS引擎在执行我们的代码, 会先执行内置代码:
    Function / Object / Number / String / Boolean / Date/...
    function Function () {}
    function Object () {}
    */

  </script>
</body>
</html>